
  var draw_heatmap = function(json, anno, ctrls, div, pfp, screentype) {

   function sortNumber(a,b) {
	      return a - b;
   } 
    /* json is the data object */   
    if(Object.keys(json).length==8){
    h = 300;
    w = 400;
	}else if(Object.keys(json).length==16){
    h = 450;
    w = 600;
    	}else {
    h = 1450;
    w = 400;
	}


    pad = {
      left: 70,
      top: 70,
      right: 20,
      bottom: 70
    };
    innerPad = 5;
    totalh = h + pad.top + pad.bottom;
    totalw = (w + pad.left + pad.right);

    var cells, colorScale, colors, corXscale, corYscale, corZscale, corr, corrplot, drawScatter, h, i, innerPad, j, nGroup, nind, nvar, pad, scatterplot, svg, totalh, totalw, w;
    
    svg = d3.select(div).append("svg").attr("height", totalh).attr("width", totalw);
  

   //################## SORTING is a hack!!!!!#################### 
   var row1=Object.keys(json)[0]
   if(typeof json[row1]=='string'){
  	x_domain=Object.keys(json[row1]).sort()
   }else{
  	x_domain=Object.keys(json[row1]).sort(sortNumber)
   }

    var x = d3.scale.ordinal()
    .domain(x_domain)
    .rangeBands([0, w]);
    var xAxis = d3.svg.axis()
    .scale(x)
    .orient("top").tickSize(h);

    var y = d3.scale.ordinal()
    .domain(Object.keys(json))
    .rangeBands([0, h]);
    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left").tickSize(-w)
    .tickFormat(function(d) {return d3.requote(d)});
   
  corrplot = svg.append("g").attr("id", "corrplot")
          .attr("transform", "translate(" + pad.left + "," + pad.top + ")");

    corrplot.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + h + ")")
    .call(xAxis);
    corrplot.append("g")
    .attr("class", "y axis")
    .call(yAxis);

 
    corr = [];
    data_array = [];
    for (i in json) {
	    for (j in json[i]) {
		    if (ctrls != null && i + j in ctrls){
			    ctrl=ctrls[i+j]
		    }else{ ctrl = null }

		    corr.push({
			    row: i,
			    col: j,
			    value: json[i][j],
			    ctrl: ctrl
		    });

		    data_array.push(json[i][j])
	    }
    }

var ctrl_cmap={'pos':'red',
	       'nt':'black',
	       'untreated':'green',
	       'nontarg':'gold',
	       'other':'yellow'
    }
    
	
	
   //################## SORTING keys is a hack!!!!!#################### 
    corXscale = d3.scale.ordinal().domain(x_domain).rangeBands([0, w]);
    corYscale = d3.scale.ordinal().domain(Object.keys(json)).rangeBands([0, h]);
    if(Math.min.apply(null, data_array)<0){
    corZscale = d3.scale.linear().domain([Math.min.apply(null, data_array), 0, Math.max.apply(null, data_array)]).range(["darkslateblue", "white", "crimson"]);
    }
    else{corZscale = d3.scale.linear().domain([Math.min.apply(null, data_array), Math.max.apply(null, data_array)]).range(["darkslateblue", "crimson"]);
	}



    /* Tooltip */
    var div=d3.select("body").append("div")   
    .attr("class", "tooltip")               
    .style("opacity", 0);





    /* draw rect */
    cells = corrplot.selectAll("empty").data(corr).enter().append("rect").attr("class", "cell"
     ).attr("x", function(d) {
      return corXscale(d.col);
    }).attr("y", function(d) {
      return corYscale(d.row);
    }).attr("width", corXscale.rangeBand())
      .attr("height", corYscale.rangeBand())
      .attr("fill", function(d) {
      return corZscale(d.value);
    }).attr("cursor", "pointer")
      .attr("stroke", function(d){
	      if (d.ctrl!=null)
      		{ //console.log(ctrl_cmap[d.ctrl.type])
			return ctrl_cmap[d.ctrl.type];}
	    	else{return "white";}})
      .attr("stroke-width", 3)
    .on("mouseover", function(d) {
	div.transition().duration(500)      
                .style("opacity", .7);
	
	if ($.isEmptyObject(anno)) {
    	html="Value:"  + d.value + " Label:" + d.row + d.col
	}  
	else {html="Value:"  + d.value + " Label:" + d.row + d.col
			+"<br/>" + anno[d.row][d.col]}
	div.html(html)  
                //.style("left", (d3.select(this).attr("x")) + "px")     
                .style("left", (d3.event.pageX) + "px")
	        .style("top", (d3.event.pageY - 28) + "px"); 


      //d3.select(this).attr("stroke", "black");  

    }).on("click", function(d){
		if (!$.isEmptyObject(anno)) {
   		 anno_txt=anno[d.row][d.col]

		 window.open("/links/?anno="+anno_txt+"&type="+screentype)

	    	 //if(screentype=='sirna')
	    	 //       {window.open("http://cancer.sanger.ac.uk/cosmic/gene/analysis?ln="+anno_txt+"&samps=1001#ts")
		 //       }
    		 //else{
	    	 //console.log(anno_txt)
	    	 //d3.text("http://cactus.nci.nih.gov/chemical/structure/"+anno_txt+"/stdinchikey", 
		 //        function(d){
		 //       	key=d.split('=')[1]
		 //       	d3.text("/getchemblID?key="+key, function(d){
		 //       	window.open("https://www.ebi.ac.uk/chembl/compound/inspect/"+
		 //       		d)
		 //       	})
		 //        })
		 //}
    	
		}
    })
    .on("mouseout", function() {
        	div.transition()        
                .duration(1000)      
                .style("opacity", 0); 
      //return d3.select(this).attr("stroke", "white");
    })
    ;




    /************** draw hits ************/

    hit_arr = [];
    if ($.isEmptyObject(pfp)!=true){
	    for (i in pfp) {
		    for (j in pfp[i]) {
			    hit_arr.push({
				    row: i,
				    col: j,
				    value: pfp[i][j]
			    });
		    }
	    }

    } else if ($.isEmptyObject(hits)!=true){
	    for (i=0;i<hits.length;i++) {
		    hit = hits[i]
	   	hit_arr.push({
				    row: hit[0],
					// a quick hack to draw H
				    col: hit[1]+hit[2],
				    value: 0
			    }
				
				);
	    }

    }

    if (hit_arr.length>0){
	    corrplot.selectAll("empty").data(hit_arr).enter().append("text")
		    .attr('x', function(d) {
			    return corXscale(d.col)+10;
		    }).attr("y", function(d) {
			    return corYscale(d.row)+20;
		    }).text(function(d) {
			    if (d.value<0.05){
				    return 'H' }
		    }).attr('fill', 'white')

    }


    /* draw the scatter plot after clicking the square in the matrix
     */
    corrplot.append("rect").attr("height", h).attr("width", w).attr("fill", "none").attr("stroke", "black").attr("stroke-width", 1).attr("pointer-events", "none");
    //scatterplot.append("rect").attr("height", h).attr("width", w).attr("fill", "none").attr("stroke", "black").attr("stroke-width", 1).attr("pointer-events", "none");
    corrplot.append("text").text("Heatmap of values").attr("id", "corrtitle").attr("x", w / 2).attr("y", -pad.top / 2).attr("dominant-baseline", "middle").attr("text-anchor", "middle");
    //scatterplot.append("text").text("Scatterplot").attr("id", "corrtitle").attr("x", w / 2).attr("y", -pad.top / 2).attr("dominant-baseline", "middle").attr("text-anchor", "middle");
    //return d3.select("div#legend").style("opacity", 1);
  }
